package com.whut.monitor.controller;


import com.alibaba.fastjson.JSON;
import com.whut.monitor.service.IHbaseService;
import com.whut.monitor.util.CombineUtil;
import com.whut.monitor.util.ProtocolUtil;
import com.whut.monitor.vo.DiagnoseSensorVo;
import com.whut.monitor.vo.HbaseVo;
import com.whut.monitor.vo.ResponseMsg;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.whut.monitor.util.HbaseUtil.fixSFTToSSTAndSFT;
import static com.whut.monitor.util.HbaseUtil.samplinArithmetic;
import static com.whut.monitor.util.WuzhongUtil.diagnosisSensorSumMsg;
import static com.whut.monitor.util.WuzhongUtil.diagnosisSensorToCache;

/**
 * @author Sandeepin
 *         HBase历史数据查询接口
 */
@Controller
@RequestMapping("/historysearch")
public class HbaseController {
    private static final Logger logger = Logger.getLogger(HbaseController.class);

    @Autowired
    private IHbaseService hbaseService;

    @RequestMapping("/manager")
    public String manager() {
        return "mintor/datahistory/historysearchsensor";
    }

    @RequestMapping("/test")
    @ResponseBody
    public String test()
    {
        String out;
        if (ProtocolUtil.TestMode) {
            out = "测试模式";
        } else {
            out = "工作模式";
        }
        return out;
    }

    @RequestMapping("/hbase")
    @ResponseBody
    public String hbaseest(String date) {
        long startTime = System.currentTimeMillis();
        String out = hbaseService.test(date);
        out += " " + (System.currentTimeMillis() - startTime) / 1000.0 + "s";
        return out;
    }

    // 查询历史数据，有抽样
    @RequestMapping("/find")
    @ResponseBody
    public HbaseVo find(String date, String idArray) {
        long startTime = System.currentTimeMillis();

        HbaseVo hbaseVo = new HbaseVo();
        Map<String, String> map = new TreeMap<>();
        String[][] valuesArray = hbaseService.finds(date, idArray, map);
        String[] dateArray = new String[map.size()];
        int i = 0;
        // map中的key存了时间
        for (String key : map.keySet()) {
            dateArray[i] = key;
            i++;
        }
        // 点数samplePoint之下则直接显示
        int samplePoint = 500;
        if (valuesArray[0].length <= samplePoint) {
            hbaseVo.setDateArray(dateArray);
            hbaseVo.setValuesArray(valuesArray);
            if (valuesArray[0].length > 0) {
                hbaseVo.setSuccess(true);
                hbaseVo.setMsg("历史数据查询成功!点数=" + valuesArray[0].length);
            }
        } else {
            String[] sampleDateArray = new String[samplePoint];
            String[][] sampleValueArray;
            // 抽样函数
            sampleValueArray = samplinArithmetic(samplePoint, dateArray, valuesArray, sampleDateArray);
            hbaseVo.setDateArray(sampleDateArray);
            hbaseVo.setValuesArray(sampleValueArray);
            hbaseVo.setSuccess(true);
            hbaseVo.setMsg("历史数据查询成功!点数=" + samplePoint);
        }

        //获取结束时间
        long endTime = System.currentTimeMillis();
        logger.info("[poi]SensorCount:" + valuesArray[0].length + "\n[poi]AllFindHbase(find):" + (endTime - startTime) + "ms =" + (endTime - startTime) / 1000 + "s");
        return hbaseVo;
    }

    // 查询历史数据，抽样个数可选
    @RequestMapping("/findbynum")
    @ResponseBody
    public HbaseVo find(int num, String date, String idArray) {
        int samplePoint = num;
        HbaseVo hbaseVo = new HbaseVo();
        Map<String, String> map = new TreeMap<>();
        String[][] valuesArray = hbaseService.finds(date, idArray, map);
        String[] dateArray = new String[map.size()];
        int i = 0;
        // map中的key存了时间
        for (String key : map.keySet()) {
            dateArray[i] = key;
            i++;
        }
        // 点数samplePoint之下则直接显示
        if (valuesArray[0].length <= samplePoint) {
            hbaseVo.setDateArray(dateArray);
            hbaseVo.setValuesArray(valuesArray);
            if (valuesArray[0].length > 0) {
                hbaseVo.setSuccess(true);
                hbaseVo.setMsg("历史数据查询成功!点数=" + valuesArray[0].length);
            }
        } else {
            if (samplePoint > 100) {
                samplePoint = 100;
            }
            String[] sampleDateArray = new String[samplePoint];
            String[][] sampleValueArray;
            // 抽样函数
            sampleValueArray = samplinArithmetic(samplePoint, dateArray, valuesArray, sampleDateArray);

            hbaseVo.setDateArray(sampleDateArray);
            hbaseVo.setValuesArray(sampleValueArray);
            hbaseVo.setSuccess(true);
            hbaseVo.setMsg("历史数据查询成功!点数=" + samplePoint);
        }
        return hbaseVo;
    }

    // 查询历史数据，无抽样（原始数据）
    @RequestMapping("/findori")
    @ResponseBody
    public HbaseVo findori(String date, String idArray) {
        // 获取开始时间
        long startTime = System.currentTimeMillis();

        HbaseVo hbaseVo = new HbaseVo();
        Map<String, String> map = new TreeMap<>();
        String[][] valuesArray = hbaseService.finds(date, idArray, map);
        String[] dateArray = new String[map.size()];
        int i = 0;
        // map中的key存了时间
        for (String key : map.keySet()) {
            dateArray[i] = key;
            i++;
        }
        hbaseVo.setDateArray(dateArray);
        hbaseVo.setValuesArray(valuesArray);
        if (valuesArray[0].length > 0) {
            hbaseVo.setSuccess(true);
            hbaseVo.setMsg("历史数据查询成功!点数=" + valuesArray[0].length);
        }

        // 获取结束时间
        long endTime = System.currentTimeMillis();
        logger.info("[poi]AllFindHbase(findori):" + (endTime - startTime) + "ms =" + (endTime - startTime) / 1000 + "s");
        return hbaseVo;
    }

    /**
     * 合表，返回合表文件位置
     *
     * @param date  用户选择的日期eg:2017-05-28
     * @param types 用户选择的需要合表的数据类型
     * @return
     */
    @RequestMapping("/combine")
    @ResponseBody
    public String combine(String date, String types) {
        //	String types = "001-DT,001-ET,001-FT,001-ST,001-CD,001-CN";前台传参格式
        CombineUtil combineUtil = new CombineUtil();
        String[][] devSenior = combineUtil.parseInputInfo(types);
        if (devSenior.length != 0) {
            String existSenior = devSenior[0][0] + ",";//存储设备号
            Map<String, String> allMap = new TreeMap<>();
            for (int i = 0; i != devSenior.length; ++i) {
                if (devSenior[i][1].equals("FT".toString())) {
                    Map<String, String> map = new TreeMap<>();
                    hbaseService.searchs(date, devSenior[i][0], devSenior[i][1], map);
                    if (map.size() != 0)//当Hbase中存在该类数据
                    {
                        existSenior += "FT,";
                        combineUtil.fbgWaveToTemp(map);
                        combineUtil.appendMap(allMap, map);
                    }
                } else if (devSenior[i][1].equals("ST".toString())) {
                    Map<String, String> ftMap = new TreeMap<>();
                    Map<String, String> stMap = new TreeMap<>();
                    hbaseService.searchs(date, devSenior[i][0], "FT", ftMap);
                    hbaseService.searchs(date, devSenior[i][0], devSenior[i][1], stMap);
                    if (ftMap.size() != 0 && ftMap.size() != 0) {
                        existSenior += "ST,";
                        combineUtil.fbgWaveToStress(stMap, ftMap);
                        combineUtil.appendMap(allMap, stMap);
                    }
                } else {//其他情况下，直接add
                    Map<String, String> map = new TreeMap<>();
                    hbaseService.searchs(date, devSenior[i][0], devSenior[i][1], map);
                    if (map.size() != 0) {
                        existSenior = existSenior + devSenior[i][1] + ",";
                        combineUtil.appendMap(allMap, map);
                    }
                }
            }
            return combineUtil.printMap(allMap, existSenior, date);//合表，返回文件路径
        }
        return "false";
    }

    @RequestMapping("/combine2csv")
    @ResponseBody
    public ResponseMsg combine2csv(String date, String start, String end, String pattern) throws IOException {
        long timeMillis = System.currentTimeMillis();

        String startTime = date + start;
        String endTime = date + end;
        String[] idArray = pattern.split("@");
        String downUrl = hbaseService.combineToCsv(startTime, endTime, idArray);

        String log = (System.currentTimeMillis() - timeMillis) / 1000.0 + "s ";
        ResponseMsg responseMsg = new ResponseMsg();
        responseMsg.setSuccess(true);
        responseMsg.setMsg(downUrl);
        responseMsg.setCost(log);
        return responseMsg;
    }

    @RequestMapping("/combine2csvzero")
    @ResponseBody
    public ResponseMsg combine2csvZero(String date, String start, String end, String pattern) throws IOException, ParseException, NoSuchAlgorithmException {
        long timeMillis = System.currentTimeMillis();

        String startTime = date + start;
        String endTime = date + end;
        // 跨天修改时间171121190000~171121070000改为171121190000~171122070000
        if (startTime.compareTo(endTime) > 0) {
            // 一天86400秒
            int deltaSecond = 86400 * 1000;
            endTime = "20" + endTime;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            Date endDate = sdf.parse(endTime);
            long endLong = endDate.getTime();
            endLong += deltaSecond;
            endTime = new SimpleDateFormat("yyMMddHHmmss").format(new Date(endLong));
        }
        String[] idArray = pattern.split("@");
        // idArray修正 - SFT拆分为SST和SFT
        String[] idArrayFix = fixSFTToSSTAndSFT(idArray);

        String downUrl = hbaseService.combineToCsvAddZero(startTime, endTime, idArrayFix);

        String log = (System.currentTimeMillis() - timeMillis) / 1000.0 + "s ";
        ResponseMsg responseMsg = new ResponseMsg();
        responseMsg.setSuccess(true);
        responseMsg.setMsg(downUrl);
        responseMsg.setCost(log);
        return responseMsg;
    }

    // 环境温度、电类传感器、FBG诊断 - 先查缓存，没有查原始数据实时计算
    @RequestMapping("/diagnosissensor")
    @ResponseBody
    public String diagnosisSensor(String date) {
        // 先查缓存 没有返回null
        String result = hbaseService.diagnosisSensorCacheFind(date);
        if (result != null) {
            if (result.length() > 100) {
                return result;
            }
        }
        // 没有查HBase原始数据、计算
        List<DiagnoseSensorVo> list = new ArrayList<>();
        Map<String, String> map = hbaseService.diagnosisSensor(date);
        for (String aKay : map.keySet()) {
            DiagnoseSensorVo diagnoseSensorVo = new DiagnoseSensorVo();
            if (aKay.contains("SET")) {
                diagnoseSensorVo.setType("【环境温度】");
            } else if (aKay.contains("SDT")) {
                diagnoseSensorVo.setType("电类温度");
            } else if (aKay.contains("SFT")) {
                diagnoseSensorVo.setType("FBG传感器");
            } else if (aKay.contains("SCD")) {
                diagnoseSensorVo.setType("CCD位移");
            }
            diagnoseSensorVo.setId(aKay);
            diagnoseSensorVo.setResult(map.get(aKay));
            list.add(diagnoseSensorVo);
        }
        result = JSON.toJSONString(list);
        hbaseService.diagnosisSensorCacheAdd("diagnosisSensor" + date, result);
        return result;
    }

    // 环境温度、电类传感器、FBG诊断 - 强制查原生数据
    @RequestMapping("/diagnosissensorori")
    @ResponseBody
    public List<DiagnoseSensorVo> diagnosisSensorOri(String date) {
        List<DiagnoseSensorVo> list = new ArrayList<>();
        Map<String, String> map = hbaseService.diagnosisSensor(date);
        for (String aKay : map.keySet()) {
            DiagnoseSensorVo diagnoseSensorVo = new DiagnoseSensorVo();
            if (aKay.contains("SET")) {
                diagnoseSensorVo.setType("【环境温度】");
            } else if (aKay.contains("SDT")) {
                diagnoseSensorVo.setType("电类温度");
            } else if (aKay.contains("SFT")) {
                diagnoseSensorVo.setType("FBG传感器");
            } else if (aKay.contains("SCD")) {
                diagnoseSensorVo.setType("CCD位移");
            }
            diagnoseSensorVo.setId(aKay);
            diagnoseSensorVo.setResult(map.get(aKay));
            list.add(diagnoseSensorVo);
        }
        String json = JSON.toJSONString(list);
        hbaseService.diagnosisSensorCacheAdd("diagnosisSensor" + date, json);
        return list;
    }

    // 环境温度、电类传感器、FBG诊断 - 强制查原生数据
    @RequestMapping("/diasensorpercent")
    @ResponseBody
    public Map<String,String> diasensorPercent(String date) {
        Map<String, String> map = hbaseService.diagnosisSensor(date);
        // 制作缓存
        String json = diagnosisSensorToCache(date, map);
        hbaseService.diagnosisSensorCacheAdd("diagnosisSensor" + date, json);

        // 故障诊断、统计信息
        Map<String, String> diagnoseSensorResultMap = new TreeMap<>();
        diagnosisSensorSumMsg(map, diagnoseSensorResultMap);
        return diagnoseSensorResultMap;
    }
}
